#import "RNSourceList.h"
#import "SourceListViewController.h"
#import "RNList.h"
#import "RNStore.h"
#import "NSCell+SRAdditions.h"
#import "RNConstants.h"
#import "RNSourceListPlaceholder.h"

@implementation RNSourceList

@synthesize sourceListController = sourceListController_;
@synthesize trackingRow = trackingRow_;
@synthesize trackingCell = trackingCell_;

+(NSMenu *)defaultMenu {
    NSMenu *theMenu = [[NSMenu alloc] initWithTitle:@"Contextual Menu"];
    [theMenu insertItemWithTitle:@"Rename…" action:@selector(renameSelectedSourceListItem:) keyEquivalent:@"" atIndex:0];
    [theMenu insertItem:[NSMenuItem separatorItem] atIndex:1];
    return theMenu;
}

-(NSMenu *)menuForEvent:(NSEvent *)theEvent {
    NSPoint eventPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil]; 
    NSInteger row = [self rowAtPoint:eventPoint];
    id representedObject = [[self itemAtRow:row] representedObject];
    if (![representedObject isKindOfClass:[RNList class]] && ![representedObject isKindOfClass:[RNStore class]])
        return nil;
    NSMenu *theMenu = [[self class] defaultMenu];
	NSString *objectType = [[representedObject className] substringFromIndex:2];
    [theMenu insertItemWithTitle:[NSString stringWithFormat:@"Delete %@", objectType] action:@selector(deleteSelectedSourceListItem:) keyEquivalent:@"" atIndex:2];
    return theMenu;
}

-(void)mouseDown:(NSEvent *)theEvent {
    NSPoint eventPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil]; 
    NSInteger rowIndex = [self rowAtPoint:eventPoint];
    id representedObject = [[self itemAtRow:rowIndex] representedObject];
    if (![representedObject isKindOfClass:[RNSourceListPlaceholder class]])
        [super mouseDown:theEvent];
    NSArray *trackingAreas = [self trackingAreas];
    NSTrackingArea *trackingArea = nil;
    for (NSTrackingArea *area in trackingAreas) {
        id userInfo = [area userInfo];
        if (![userInfo isKindOfClass:[NSDictionary class]])
            continue;
        id rowNumber = [userInfo valueForKey:RNRowKey];
        if (!rowNumber)
            continue;
        trackingArea = area;
        break;
    }
    if (!trackingArea)
        return;
    NSRect placeholderRect = [trackingArea rect];
    NSCell *placeholderCell = [self preparedCellAtColumn:0 row:rowIndex];
    NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
    if ([self mouse:point inRect:placeholderRect])
        [placeholderCell trackMouse:theEvent inRect:placeholderRect ofView:self untilMouseUp:YES];
}

- (void)rightMouseDown:(NSEvent *)theEvent {
    NSPoint eventPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil]; 
    NSInteger row = [self rowAtPoint:eventPoint];
    id representedObject = [[self itemAtRow:row] representedObject];
    if (![representedObject isKindOfClass:[RNList class]] && ![representedObject isKindOfClass:[RNStore class]])
        return;
    [self selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
    [super rightMouseDown:theEvent];
}

-(BOOL)acceptsFirstResponder {
    return NO;
}

- (NSRect)frameOfOutlineCellAtRow:(NSInteger)row {
    return NSZeroRect;
}

- (void)editColumn:(NSInteger)columnIndex row:(NSInteger)rowIndex withEvent:(NSEvent *)theEvent select:(BOOL)flag {
    id item = [[self itemAtRow:rowIndex] representedObject];
    if (![item isKindOfClass:[RNList class]] && ![item isKindOfClass:[RNStore class]])
        return;
    [super editColumn:columnIndex row:rowIndex withEvent:theEvent select:flag];
}

- (void)updateCell:(NSCell *)aCell {
    if (aCell == [self trackingCell]) {
        [self setNeedsDisplayInRect:[self frameOfCellAtColumn:0 row:[self trackingRow]]];
    }
    [super updateCell:aCell];
}

- (void)mouseEntered:(NSEvent *)event {
    NSDictionary *userInfo = [event userData];
    NSNumber *row = [userInfo valueForKey:RNRowKey];
    if (!row) 
        return;
    NSInteger rowValue = [row integerValue]; 
    NSCell *cell = [self preparedCellAtColumn:0 row:rowValue];
    [self setTrackingRow:rowValue];
    [self setTrackingCell:[cell copy]];
    id representedObject = [[self itemAtRow:rowValue] representedObject];
    [[self trackingCell] setRepresentedObject:representedObject];
    [[self trackingCell] setControlView:self];
    [[self trackingCell] mouseEntered:event];
}

- (void)mouseExited:(NSEvent *)event {
    NSDictionary *userInfo = [event userData];
    NSNumber *row = [userInfo valueForKey:RNRowKey];
    if (!row) 
        return;
    NSCell *cell = [self preparedCellAtColumn:0 row:[row integerValue]];
    [cell mouseExited:event];
    [self setTrackingCell:nil];
    [self setTrackingRow:-1];
}

- (NSCell *)preparedCellAtColumn:(NSInteger)column row:(NSInteger)row {
    if ([self selectedCell] == nil && row == [self trackingRow]) 
        return [self trackingCell];
    id representedObject = [[self itemAtRow:row] representedObject];
    NSCell *cell = [super preparedCellAtColumn:column row:row];
    [cell setRepresentedObject:representedObject];
    return cell;
}

-(void)updateTrackingAreas {
    for (NSTrackingArea *area in [self trackingAreas])
        [self removeTrackingArea:area];
    
    NSPoint mouseLocation = [self convertPoint:[[self window] convertScreenToBase:[NSEvent mouseLocation]] fromView:nil];
    NSRange visibleRows = [self rowsInRect:[self visibleRect]];
    for (NSUInteger row = visibleRows.location; row < NSMaxRange(visibleRows); row++ ) {
        NSCell *visibleCell = [self preparedCellAtColumn:0 row:row];
        if (![visibleCell respondsToSelector:@selector(addTrackingAreasForView:inRect:withUserInfo:mouseLocation:)]) 
            continue;
        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInteger:row] forKey:RNRowKey];
        [visibleCell addTrackingAreasForView:self inRect:[self frameOfCellAtColumn:0 row:row] withUserInfo:userInfo mouseLocation:mouseLocation];
    }
}

@end
